<?php
/**
 * @copyright © 2022 by 技术先锋 All rights reserved
 * @created   by PhpStorm.
 * @author    starsphp
 * @date      2023/3/29
 * @time      17:59
 */
declare (strict_types=1);

namespace utils\workerman;

use think\event\RouteLoaded;
use think\Request;
use think\Response;
use Throwable;
use utils\workerman\http\ResponseFile;

/**
 *
 * Class Http
 *
 * @package utils\workerman
 * @project name workerman-tp6
 * @created by PhpStorm.
 * @author  starsphp
 * @date    2023/3/29
 * @time    18:00
 */
class Http extends \think\Http
{
    /**
     * 中间件加载标记
     * @var bool $loadMiddlewareFlag
     */
    protected static bool $loadMiddlewareFlag = false;
    
    /**
     * 路由加载标记
     * @var bool $loadRoutesFlag
     */
    protected static bool $loadRoutesFlag = false;
    
    protected function loadMiddleware(): void
    {
        if (self::$loadMiddlewareFlag) {
            return;
        }
        
        if (is_file($this->app->getBasePath() . 'middleware.php')) {
            self::$loadMiddlewareFlag = true;
            // Change include to include_once
            $this->app->middleware->import(include_once $this->app->getBasePath() . 'middleware.php');
        }
    }
    
    protected function loadRoutes(): void
    {
        if (self::$loadRoutesFlag) {
            $this->loadRoutesEvent();
            return;
        }
        
        $routePath = $this->getRoutePath();
        
        if (is_dir($routePath)) {
            $files = glob($routePath . '*.php');
            foreach ($files as $file) {
                // Change include to include_once
                include_once $file;
            }
        }
        self::$loadRoutesFlag = true;
        $this->loadRoutesEvent();
    }
    
    protected function loadRoutesEvent()
    {
        $this->app->event->trigger(RouteLoaded::class);
    }
    
    /**
     * 执行应用程序
     * @access public
     * @param Request|null $request
     * @return Response
     */
    public function run(Request $request = null): Response
    {
        //初始化
        $this->initialize();
        
        //自动创建request对象
        $request = $request ?? $this->app->make('request', [], true);
        $this->app->instance('request', $request);
        
        try {
            $file = $this->app->getRootPath() . 'public' . DIRECTORY_SEPARATOR . $request->pathinfo();
            if (is_file($file)) {
                $response =  new ResponseFile($file);
            } else {
                $response = $this->runWithRequest($request);
            }
            
        } catch (Throwable $e) {
            $this->reportException($e);
            
            $response = $this->renderException($request, $e);
        }
        
        return $response;
    }
    
    /**
     * __destruct.
     *
     * @return void
     */
    public function __destruct()
    {
        dump('__destruct');
        if (isset($this->_data['files'])) {
            \clearstatcache();
            \array_walk_recursive($this->_data['files'], function($value, $key){
                if ($key === 'tmp_name') {
                    if (\is_file($value)) {
                        \unlink($value);
                    }
                }
            });
        }
    }
}
